#!/usr/bin/perl
package genfile;
	$VERSION = '0.1';
	require Exporter;
	BEGIN {
	    @ISA = qw(Exporter);
	    @EXPORT = qw(
						scrivi_file 
						leggi_file 
						leggi_file_array 
						copia
						copiaSeNonEsiste
						fileDosFormat 
						readXmlConfiguration 
						overwriteContent 
						overwriteParameters 
						backup_files 
						restore_file 
						restore_files );
	}

use File::Path; #necessaria per mkpath
use genutil;

#--------------------------------
#	FILES I/O
#--------------------------------
sub scrivi_file { 
	# scrive $content in $nomeFile
	my ($nomeFile, $content) = @_;
	
	#TODO: $nomeFile=osPath($nomeFile);
	
	open(F,">$nomeFile");
	print F $content;
	close(F);
}
sub leggi_file {
	#ritorna il file come una sola stringa
	my ($nomeFile) = @_;

	#TODO: $nomeFile=osPath($nomeFile);
	open(F,"$nomeFile");
	my $content = '';
	my @asContent = <F>;
	foreach(@asContent){$content.=$_;}
	close(F);
	return $content;
}
sub leggi_file_array {	
	#ritorna l'array delle righe del file
	my ($nomeFile) = @_;
	#TODO: $nomeFile=osPath($nomeFile);

	open(F,"$nomeFile");
	my @asContent = <F>;
	close(F);
	return \@asContent;
}
#----------------------------------------

sub copia {
	my ( $fileSrc, $fileDst  ) = @_;

	if( $fileSrc eq $fileDst ) {
		OUT( qq|NESSUNA COPIA: src e dst file coincidono: $fileSrc\n| );
		return;
	}
	open( F, "$fileSrc" );
	my @righe = <F>;
	close(F);
	#
	#	creazione dir se non esiste
	#
	my $dir = $fileDst;
	$dir =~ s/\/[^\/]+$//;
	if( ! -e $dir ) {
		#$cmd = qq|mkdir -p $dir|;  print $cmd;	$ris = qx|$cmd|;
		OUT( qq|creo directory $dir\n| );
		mkpath( $dir );
	}
	open( F, ">$fileDst" );
	foreach $r (@righe)	{print F $r;}
	close(F);
}
#----------------------------------------

sub copiaSeNonEsiste {
	my ( $fileSrc, $fileDst  ) = @_;
	if( -e $fileDst ) {
	    OUT( qq|NESSUNA COPIA: file dst esiste già: $fileDst\n| );
	}else{
	    copia($fileSrc, $fileDst );
	}
}
#----------------------------------------

sub osPath {	
	my ( $nomeFile )=@_;
	if( $^O =~ /win/i ){
		return 	fileDosFormat($nomeFile);
	}else{
		return $nomeFile;
	}
}

sub fileDosFormat {
	# trasforma /c/script/pippo/pluto in c:\script\pippo\pluto
	my ( $strFiles )=@_;
	my @files = split( /\n/, $strFiles);
	my ($f, $out) = ('','');

	foreach $f (@files) {
		if( $f !~ /\// ) {next;}
		if( $f =~ /^\s*([^\s]+)\s*$/ ) {
			$f = $1;
		}
		
		$f =~ s/^\/c\//c:\\/i;	
		$f =~ s/\//\\/g;	
		if( $f !~ /^c:\\/ ) {
			$f = "c:\\$f";
		}
		$out .= "$f\n";
	}
	return $out;
}


##########################################
#		LETTURA FILE XML DI CONFIGURAZIONE
#	viene implementata la gerarchia tra files XML. E' possibile far estendere un file FF da un file-padre FP.
#	Se FF non definisce un parametro, viene preso quello di FP, altrimenti quello di FF sovrascrive quello di FP.
##########################################

sub readXmlConfiguration {
	my ($filexml) =@_;
	
	my $config = XMLin( $filexml,  ForceArray => [ 'p', 'gen', 'cicle', 'column' ]	);
	
	if( $config->{'extends'} ne '' ){
		$configBase = readXmlConfiguration( $config->{'extends'} ); ## RICORSIONE sula gerarchia dei file XML ##
	
		#files
		overwriteContent(	$config, $configBase, 'new-files' );
		overwriteContent(	$config, $configBase, 'target-files' );
		overwriteContent(	$config, $configBase, 'findreplace-files' );
		overwriteContent(	$config, $configBase, 'perl-library' );	

		#placeholder
		overwriteContent(	$config, $configBase, 'placeholder-new' );	
		overwriteContent(	$config, $configBase, 'placeholder-fr' );	
		overwriteContent(	$config, $configBase, 'placeholder-gen' );	
		
		#parameters
		overwriteParameters(	$config, $configBase, 'system-parameters', 'p' );
		overwriteParameters(	$config, $configBase, 'remote-parameters', 'p' );
		overwriteParameters(	$config, $configBase, 'parameters', 'p' );
		overwriteParameters(	$config, $configBase, 'calculated-parameters', 'p' );
		
		#code-generations
		overwriteParameters(	$config, $configBase, 'code-generations', 'gen' );
	}
	
	return $config;
}

sub overwriteContent {
	my ($config, $configBase, $name) = @_;

	if( ! exists( $config->{$name} )){ # == undef || ref( $config->{$name} ) eq 'HASH' ){
		$config->{$name} = '';
	}

	if( $config->{$name} eq '' ){
		$config->{$name} = $configBase->{$name};
	}
	
#	print Dumper( $config->{$name}); die(1);
#	print Dumper( $config );
#	die( qq|$name = $config->{$name}	|);
}

sub overwriteParameters {
	my ($config, $configBase, $name, $namePlace) =@_;
	if(( $configBase->{$name} == undef )||( $configBase->{$name}->{$namePlace} == undef )) {
		return;
	}
	if( $config->{$name} == undef ) {
		$config->{$name} = {};
	}
	if( $config->{$name}->{$namePlace} == undef ) {
		$config->{$name}->{$namePlace} = {};
	}

	my $parameters = $config->{$name}->{$namePlace};
	my $parametersBase = $configBase->{$name}->{$namePlace};
	
	foreach $k (keys(%$parametersBase)){
		if( $parameters->{$k} == undef ){
			$parameters->{$k} = $parametersBase->{$k};
		}
	}
}

#------------------------------------------------------
#	backup e restore dei files
#------------------------------------------------------
sub backup_files {
	#backup del file in caso di definizione della dir di backup e di esistenza dei file
	my ( $arrayFiles, $backupDir ) = @_;
	if( $backupDir eq '' )  {return;}
	
	foreach $f (@$arrayFiles) { 
		if( -e $f ) {
			my $backupFile = $backupDir . $f;		#	DEBUG( "backup:$f\n" );
			copia( $f, $backupFile );	
		}
	}
}

sub restore_file {
	my ($f, $p) = @_;
	my %p=%$p;

	#restore dei files in caso di definizione della dir di backup
	if( $p{'backup-dir'} ne '' ){
		DEBUG( "restore:$f\n" );
		unlink($f);
		if( -e "$p{'backup-dir'}$f" ){
			copia( "$p{'backup-dir'}$f", $f );
		}
	}
}

sub restore_files {
	#backup del file in caso di definizione della dir di backup e di esistenza dei file
	my ( $arrayFiles, $backupDir ) = @_;
	if( $backupDir eq '' ) {return;}
	
	foreach $f (@$arrayFiles) { 
		my $backupFile = $backupDir . $f;		#	DEBUG( "backup:$f\n" );
		if( -e $backupFile ) {
			DEBUG( "restore:$f\n" );
			unlink($f);
			copia( $backupFile, $f );	
		}
	}
}

1;
